package week8;

import java.util.Scanner;

/**
 * Klasse voor het onderhouden van het BoterKaasEieren-spel.
 * Practicumopdracht P1.
 * @author  Theo Ruys en Arend Rensink
 * @version $Revision: 1.4 $
 */
public class Spel {

    // -- Instance variables -----------------------------------------

    public static final int AANTAL_SPELERS = 2;

    /**
     * Het speelbord. 
     * @invariant bord != null
     */
    private Bord bord;       

    /**
     * De twee spelers van het spel.
     * @invariant spelers.length == AANTAL_SPELERS,
     *            spelers[0] != null, spelers[1] != null
     */
    private Speler[] spelers;        

    /** 
     * Index van huidige speler. 
     * @invariant 0 <= huidig < AANTAL_SPELERS
     */
    private int huidig;  

    // -- Constructors -----------------------------------------------

    /**
     * Construeert een nieuw Spel object.
     * @param   s0 de eerste Speler
     * @param   s1 de tweede Speler
     * @require <code>s0 != null && s1 != null</code>
     */
    public Spel(Speler s0, Speler s1) {
        bord       = new Bord();
        spelers    = new Speler[AANTAL_SPELERS];
        spelers[0] = s0;
        spelers[1] = s1;
        huidig     = 0;
    }

    // -- Commands ---------------------------------------------------

    /**
     * Start het BoterKaasEieren spel. <br>
     * Vraagt na elk beeindigd spel of er doorgespeeld moet worden.
     * Blijft doorspelen totdat de gebruikers niet meer willen spelen.
     */
    public void start() {
        boolean doorgaan = true;
        while (doorgaan) {
            reset();
            play();
            doorgaan = leesBoolean("\n> Nog een keer (j/n)?", "j", "n");
        }
    }
    
    /**
     * Stelt de gebruiker een vraag waarop ja (true) of nee (false) kan
     * worden geantwoord. De methode schrijft eerst de prompt naar de
     * standaard uitvoer. Daarna leest de methode een String die 
     * vergeleken wordt met de parameters ja of nee. Als de ingelezen
     * String overeenkomt met de parameter ja wordt true opgeleverd en
     * als de String overeenkomt met de parameter nee wordt false
     * opgeleverd. In alle andere gevallen wordt de vraag nogmaals
     * gesteld. De methode eindigt pas als ofwel het ja-antwoord ofwel\
     * het nee-antwoord is gegeven.
     * @parom  prompt de vraag die gesteld wordt
     * @param  ja  de String de correspondeert met het ja-antwoord
     * @param  nee de String de correspondeert met het nee-antwoord
     * @return true als het ja-antwoord is ingetypt, 
     *         false als het nee-antwoord is ingetypt.
     */
    private boolean leesBoolean(String prompt, String ja, String nee) {
        String antwoord; 
        do {
            System.out.print(prompt);        
            Scanner in = new Scanner(System.in);
            antwoord   = in.hasNextLine() ? in.nextLine() : null;
        } while ( antwoord == null ||
                  (!antwoord.equals(ja) && !antwoord.equals(nee)));                  
        return antwoord.equals(ja);
    }

    /**
     * Reset dit spel. <br>
     * Het speelbord wordt leeggemaakt en spelers[0] wordt de huidige speler.
     */
    private void reset() {
        huidig = 0;
        bord.reset();
    }

    /**
     * Speelt een Boter-Kaas-Eieren spel. <br>
     * Eerst wordt het (nog lege) speelbord getoond.
     * Daarna wordt er doorgespeeld totdat het spel afgelopen is.
     * De spelers mogen om-en-om een zet doen.
     * Na elke zet wordt het veranderde speelbord getoond.
     */
    private void play() {
		update();
		while(!bord.gameOver()){
			spelers[huidig].doeZet(bord);
			huidig++;
			huidig %= AANTAL_SPELERS;
			update();
		}
		schrijfUitslag();
    }

    /**
     * Schrijft de toestand van het spel naar de standaarduitvoer.
     */
    private void update() {
        System.out.println("\nHuidige toestand: \n\n"+ bord.toString()+"\n");
    }

    /**
     * Schrijft de uitslag van het laatste spel naar de standaarduitvoer. <br>
     * @require bord.gameOver()
     */
    private void schrijfUitslag() {
        if (bord.heeftWinnaar()) {
            Speler winnaar = bord.isWinnaar(spelers[0].getMark()) ?
                             spelers[0] : spelers[1];
            System.out.println("Speler " + winnaar.getNaam() +
                               " (" + winnaar.getMark().toString() + 
                               ") heeft gewonnen!");
        } else {
            System.out.println("Remise. Er is geen winnaar!");
        }
    }
} // end of class Spel
